import { Sprite, Texture } from 'pixi.js';
import { Body, World } from 'matter-js';
import { Entity, EntityConfig } from './Entity';
import { Player } from './Player';
import { useGameStore } from '../../store/gameStore';

export interface EnemyConfig extends EntityConfig {
  speed?: number;
  health?: number;
  damage?: number;
  detectionRadius?: number;
  attackRadius?: number;
  attackCooldown?: number;
  patrolRadius?: number;
  aggressiveness?: number;
}

export enum EnemyState {
  IDLE,
  PATROL,
  CHASE,
  ATTACK,
  STUNNED,
  RETREAT
}

export class Enemy extends Entity {
  private speed: number;
  private health: number;
  private damage: number;
  private detectionRadius: number;
  private attackRadius: number;
  private attackCooldown: number;
  private attackCooldownTimer: number;
  private state: EnemyState;
  private target: Player | null;
  private stunTimer: number;
  private patrolRadius: number;
  private patrolPoint: { x: number; y: number };
  private patrolTimer: number;
  private aggressiveness: number; // 0-1之间，影响追击意愿
  private lastKnownTargetPos: { x: number; y: number } | null;
  private retreatTimer: number;

  constructor(config: EnemyConfig) {
    super(config);
    
    // 初始化敌人属性
    this.speed = config.speed || 2;
    this.health = config.health || 100;
    this.damage = config.damage || 10;
    this.detectionRadius = config.detectionRadius || 200;
    this.attackRadius = config.attackRadius || 50;
    this.attackCooldown = config.attackCooldown || 1000; // 毫秒
    this.patrolRadius = config.patrolRadius || 100;
    this.aggressiveness = config.aggressiveness || 0.7;
    
    // 状态初始化
    this.attackCooldownTimer = 0;
    this.state = EnemyState.IDLE;
    this.target = null;
    this.stunTimer = 0;
    this.patrolPoint = { x: this.x, y: this.y };
    this.patrolTimer = 0;
    this.lastKnownTargetPos = null;
    this.retreatTimer = 0;
    
    // 添加敌人标签
    this.addTag('enemy');
  }

  // 设置目标
  public setTarget(player: Player): void {
    this.target = player;
  }

  // 受到伤害
  public takeDamage(amount: number): void {
    this.health -= amount;
    
    // 受击时短暂眩晕
    this.state = EnemyState.STUNNED;
    this.stunTimer = 300; // 眩晕300毫秒
    
    // 记录玩家位置，用于后续追击
    if (this.target) {
      this.lastKnownTargetPos = this.target.getPosition();
    }
    
    if (this.health <= 0) {
      this.deactivate(); // 敌人死亡
    } else if (this.health < 30 && Math.random() > this.aggressiveness) {
      // 血量低且不够激进时可能会撤退
      this.state = EnemyState.RETREAT;
      this.retreatTimer = 2000; // 撤退2秒
    }
  }

  // 攻击目标
  private attackTarget(): void {
    if (this.target && this.attackCooldownTimer <= 0) {
      // 检查目标是否处于无敌状态
      if (!this.target.isInvulnerableState()) {
        // 触发伤害事件
        const gameStore = useGameStore.getState();
        gameStore.takeDamage(this.damage);
        
        // 重置攻击冷却
        this.attackCooldownTimer = this.attackCooldown;
      }
    }
  }

  // 生成新的巡逻点
  private generateNewPatrolPoint(): void {
    const angle = Math.random() * Math.PI * 2;
    const distance = Math.random() * this.patrolRadius;
    
    this.patrolPoint = {
      x: this.x + Math.cos(angle) * distance,
      y: this.y + Math.sin(angle) * distance
    };
    
    this.patrolTimer = 3000 + Math.random() * 2000; // 3-5秒后更换巡逻点
  }

  // 执行巡逻行为
  private patrol(delta: number): void {
    this.patrolTimer -= delta;
    
    if (this.patrolTimer <= 0) {
      this.generateNewPatrolPoint();
    }
    
    // 计算到巡逻点的方向
    const dx = this.patrolPoint.x - this.x;
    const dy = this.patrolPoint.y - this.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    
    // 如果已经接近巡逻点，生成新的巡逻点
    if (distance < 10) {
      this.generateNewPatrolPoint();
      return;
    }
    
    // 移动到巡逻点
    const dirX = dx / distance;
    const dirY = dy / distance;
    const patrolSpeed = this.speed * 0.6; // 巡逻速度较慢
    
    const newX = this.x + dirX * patrolSpeed;
    const newY = this.y + dirY * patrolSpeed;
    this.setPosition(newX, newY);
  }

  // 执行撤退行为
  private retreat(delta: number): void {
    this.retreatTimer -= delta;
    
    if (this.retreatTimer <= 0 || this.health > 50) {
      // 撤退结束或血量恢复，回到巡逻状态
      this.state = EnemyState.PATROL;
      this.generateNewPatrolPoint();
      return;
    }
    
    if (!this.target) return;
    
    // 计算远离玩家的方向
    const targetPos = this.target.getPosition();
    const dx = this.x - targetPos.x;
    const dy = this.y - targetPos.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    
    // 如果已经足够远，停止撤退
    if (distance > this.detectionRadius * 1.5) {
      this.state = EnemyState.PATROL;
      this.generateNewPatrolPoint();
      return;
    }
    
    // 移动方向（远离玩家）
    const dirX = dx / distance;
    const dirY = dy / distance;
    const retreatSpeed = this.speed * 1.2; // 撤退速度较快
    
    const newX = this.x + dirX * retreatSpeed;
    const newY = this.y + dirY * retreatSpeed;
    this.setPosition(newX, newY);
  }

  // 更新敌人状态
  public update(delta: number): void {
    // 更新计时器
    if (this.attackCooldownTimer > 0) {
      this.attackCooldownTimer -= delta;
    }
    
    if (this.stunTimer > 0) {
      this.stunTimer -= delta;
      if (this.stunTimer <= 0) {
        // 眩晕结束后，根据情况决定下一个状态
        if (this.health < 30 && Math.random() > this.aggressiveness) {
          this.state = EnemyState.RETREAT;
          this.retreatTimer = 2000;
        } else {
          this.state = EnemyState.IDLE;
        }
      }
      return; // 眩晕状态下不执行其他逻辑
    }
    
    // 处理撤退状态
    if (this.state === EnemyState.RETREAT) {
      this.retreat(delta);
      return;
    }
    
    // 没有目标或目标无效时进入巡逻状态
    if (!this.target || !this.target.isEntityActive()) {
      if (this.state !== EnemyState.PATROL) {
        this.state = EnemyState.PATROL;
        this.generateNewPatrolPoint();
      }
      this.patrol(delta);
      return;
    }
    
    // 获取与目标的距离
    const targetPos = this.target.getPosition();
    const dx = targetPos.x - this.x;
    const dy = targetPos.y - this.y;
    const distanceToTarget = Math.sqrt(dx * dx + dy * dy);
    
    // 根据距离更新状态
    if (distanceToTarget <= this.attackRadius) {
      this.state = EnemyState.ATTACK;
      this.attackTarget();
      // 记录最后已知的玩家位置
      this.lastKnownTargetPos = targetPos;
    } else if (distanceToTarget <= this.detectionRadius) {
      // 根据侵略性决定是否追击
      if (Math.random() < this.aggressiveness) {
        this.state = EnemyState.CHASE;
        
        // 计算移动方向
        const dirX = dx / distanceToTarget;
        const dirY = dy / distanceToTarget;
        
        // 更新位置
        const newX = this.x + dirX * this.speed;
        const newY = this.y + dirY * this.speed;
        this.setPosition(newX, newY);
        
        // 记录最后已知的玩家位置
        this.lastKnownTargetPos = targetPos;
      } else {
        // 不够激进，进入巡逻状态
        if (this.state !== EnemyState.PATROL) {
          this.state = EnemyState.PATROL;
          this.generateNewPatrolPoint();
        }
        this.patrol(delta);
      }
    } else if (this.lastKnownTargetPos && this.state === EnemyState.CHASE) {
      // 玩家超出检测范围但有最后已知位置，继续向该位置移动
      const dx = this.lastKnownTargetPos.x - this.x;
      const dy = this.lastKnownTargetPos.y - this.y;
      const distance = Math.sqrt(dx * dx + dy * dy);
      
      if (distance < 10) {
        // 已到达最后已知位置，进入巡逻状态
        this.lastKnownTargetPos = null;
        this.state = EnemyState.PATROL;
        this.generateNewPatrolPoint();
        this.patrol(delta);
      } else {
        // 继续向最后已知位置移动
        const dirX = dx / distance;
        const dirY = dy / distance;
        const newX = this.x + dirX * this.speed;
        const newY = this.y + dirY * this.speed;
        this.setPosition(newX, newY);
      }
    } else {
      // 进入巡逻状态
      if (this.state !== EnemyState.PATROL) {
        this.state = EnemyState.PATROL;
        this.generateNewPatrolPoint();
      }
      this.patrol(delta);
    }
  }

  // 获取当前状态
  public getState(): EnemyState {
    return this.state;
  }

  // 获取当前生命值
  public getHealth(): number {
    return this.health;
  }

  // 销毁实例
  public destroy(): void {
    if (this.sprite && !this.sprite.destroyed) {
      this.sprite.destroy();
    }
    if (this.body && this.body.world) {
      World.remove(this.body.world, this.body);
    }
  }
}